<template>
  <div class="methane-monitor" :class="{ 'is-collapsed': collapsed }">
    <div class="monitor-banner" @click="toggleCollapse">
      <div class="banner-main">
        <span class="banner-title">{{ title }}</span>
        <span class="banner-value">
          {{ formattedValue }}<small class="banner-unit">{{ unit }}</small>
        </span>
      </div>
      <div class="banner-meta">
        <span class="status-indicator" :class="statusClass"></span>
        <span class="status-text">{{ statusLabel }}</span>
        <span class="trend" v-if="trendInfo">
          <span class="trend-icon" :class="trendInfo.direction">
            {{ trendSymbol }}
          </span>
          {{ trendInfo.label }}
        </span>
        <i
          class="iconfont icon-zhankai collapse-icon"
          :class="{ rotated: collapsed }"
        ></i>
      </div>
    </div>
    <transition name="fade">
      <div v-show="!collapsed" class="monitor-body">
        <div v-if="chartReady" ref="chartRef" class="chart"></div>
        <div v-else class="chart-placeholder">等待甲烷数据...</div>
      </div>
    </transition>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import * as echarts from "echarts";
import { useMethaneMonitor } from "@/utils/useMethaneMonitor";

const props = defineProps({
  mqttUrl: {
    type: String,
    default: undefined,
  },
  topic: {
    type: String,
    default: undefined,
  },
  title: {
    type: String,
    default: "甲烷浓度",
  },
  unit: {
    type: String,
    default: "ppm",
  },
});

const collapsed = ref(false);
const chartRef = ref(null);
let chartInstance = null;

const { currentValue, history, status } = useMethaneMonitor({
  url: props.mqttUrl,
  topic: props.topic,
});

const formattedValue = computed(() => {
  if (typeof currentValue.value !== "number") {
    return "--";
  }
  return currentValue.value.toFixed(2);
});

const statusLabel = computed(() => {
  switch (status.value) {
    case "connected":
      return "已连接";
    case "connecting":
      return "连接中";
    case "reconnecting":
      return "重连中";
    case "error":
      return "异常";
    default:
      return "未连接";
  }
});

const statusClass = computed(() => {
  return {
    connected: status.value === "connected",
    warning: status.value === "connecting" || status.value === "reconnecting",
    error: status.value === "error",
  };
});

const chartReady = computed(() => history.value.length > 1);

const trendInfo = computed(() => {
  if (history.value.length < 2) return null;
  const [prev, last] = history.value.slice(-2);
  const delta = last.value - prev.value;
  if (Math.abs(delta) < 0.01) {
    return { label: "持平", direction: "flat" };
  }
  return {
    label: `${delta > 0 ? "上升" : "下降"}${Math.abs(delta).toFixed(2)}`,
    direction: delta > 0 ? "up" : "down",
  };
});

const trendSymbol = computed(() => {
  if (!trendInfo.value) return "";
  if (trendInfo.value.direction === "up") return "↑";
  if (trendInfo.value.direction === "down") return "↓";
  return "→";
});

function toggleCollapse() {
  collapsed.value = !collapsed.value;
  if (!collapsed.value) {
    nextTickResize();
  }
}

function initialiseChart() {
  if (!chartRef.value) return;
  chartInstance = echarts.init(chartRef.value);
  chartInstance.setOption(getBaseOption());
}

function disposeChart() {
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
}

function getBaseOption() {
  return {
    animation: true,
    backgroundColor: "transparent",
    grid: { left: 20, right: 12, top: 18, bottom: 18 },
    tooltip: {
      trigger: "axis",
      backgroundColor: "rgba(17, 24, 39, 0.9)",
      borderWidth: 0,
      textStyle: { color: "#e0f2f1" },
    },
    xAxis: {
      type: "category",
      boundaryGap: false,
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: "rgba(226, 232, 240, 0.7)",
        formatter: (value) => value,
      },
    },
    yAxis: {
      type: "value",
      boundaryGap: [0.05, 0.1],
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: {
        lineStyle: {
          color: "rgba(148, 163, 184, 0.15)",
          type: "dashed",
        },
      },
      axisLabel: {
        color: "rgba(226, 232, 240, 0.6)",
      },
    },
    series: [
      {
        name: props.title,
        type: "line",
        showSymbol: false,
        smooth: true,
        lineStyle: {
          color: "#2dd4bf",
          width: 2,
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: "rgba(45, 212, 191, 0.35)" },
            { offset: 1, color: "rgba(45, 212, 191, 0.05)" },
          ]),
        },
        data: [],
      },
    ],
  };
}

function updateChart(entries) {
  if (!chartInstance) return;
  const labels = entries.map((item) => formatTimestamp(item.timestamp));
  const values = entries.map((item) => Number(item.value));

  chartInstance.setOption({
    xAxis: { data: labels },
    series: [{ data: values }],
  });
}

function formatTimestamp(timestamp) {
  if (!timestamp) return "--";
  const date = new Date(timestamp);
  return date.toLocaleTimeString("zh-CN", {
    hour12: false,
    minute: "2-digit",
    second: "2-digit",
  });
}

function handleResize() {
  if (chartInstance) {
    chartInstance.resize();
  }
}

function nextTickResize() {
  requestAnimationFrame(() => {
    handleResize();
  });
}

watch(
  history,
  (entries) => {
    if (!entries || entries.length === 0) return;
    if (!chartInstance) {
      initialiseChart();
    }
    updateChart(entries);
  },
  { deep: true }
);

onMounted(() => {
  if (chartReady.value) {
    initialiseChart();
    updateChart(history.value);
  }
  window.addEventListener("resize", handleResize);
});

onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
  disposeChart();
});

defineExpose({
  reconnect: () => {
    if (status.value !== "connected") {
      chartInstance && chartInstance.showLoading();
    }
  },
});
</script>

<style scoped>
.methane-monitor {
  width: 320px;
  border-radius: 16px;
  background: rgba(17, 24, 39, 0.72);
  box-shadow: 0 20px 40px rgba(15, 23, 42, 0.35);
  backdrop-filter: blur(10px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.methane-monitor.is-collapsed {
  transform: translateX(calc(-100% + 35px));
}

.monitor-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 14px;
  background: linear-gradient(
    135deg,
    rgba(45, 212, 191, 0.15),
    rgba(30, 64, 175, 0.05)
  );
  cursor: pointer;
}

.banner-main {
  display: flex;
  flex-direction: column;
}

.banner-title {
  font-size: 11px;
  color: rgba(226, 232, 240, 0.85);
  letter-spacing: 0.4px;
}

.banner-value {
  font-size: 26px;
  font-weight: 600;
  color: #2dd4bf;
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.banner-unit {
  font-size: 13px;
  color: rgba(148, 163, 184, 0.85);
}

.banner-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  color: rgba(226, 232, 240, 0.75);
  font-size: 12px;
}

.status-indicator {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(148, 163, 184, 0.6);
  box-shadow: 0 0 0 4px rgba(148, 163, 184, 0.15);
  transition: background 0.3s ease, box-shadow 0.3s ease;
}

.status-indicator.connected {
  background: #22d3ee;
  box-shadow: 0 0 0 4px rgba(34, 211, 238, 0.18);
}

.status-indicator.warning {
  background: #f97316;
  box-shadow: 0 0 0 4px rgba(249, 115, 22, 0.18);
}

.status-indicator.error {
  background: #ef4444;
  box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.25);
}

.trend {
  display: flex;
  align-items: center;
  gap: 4px;
  color: rgba(226, 232, 240, 0.75);
}

.trend-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
}

.trend-icon.up {
  color: #22d3ee;
}

.trend-icon.down {
  color: #fb7185;
}

.trend-icon.flat {
  color: rgba(226, 232, 240, 0.65);
}

.collapse-icon {
  font-size: 14px;
  transition: transform 0.3s ease;
}

.collapse-icon.rotated {
  transform: rotate(180deg);
}

.monitor-body {
  padding: 10px 12px 16px;
}

.chart {
  width: 100%;
  height: 160px;
}

.chart-placeholder {
  height: 160px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(148, 163, 184, 0.8);
  font-size: 13px;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

@media (max-width: 1080px) {
  .methane-monitor {
    width: 260px;
  }

  .chart {
    height: 130px;
  }
}
</style>
